package nf;

import java.util.*;
import nf.graph.*;
import nf.utility.*;
import nf.util.Rational;
import nf.util.ArgumentParser;
import nf.util.ArgumentParseException;

public class Utility
{
	private static void printUtilities(Graph graph, boolean quiet,
		final String targetNodeName)
	{
		UtilityCalculator uc = new SimpleUtilityCalculator();
		
		if (targetNodeName != null) {
			uc.addTracer(new UtilityTracer() {
				public void traceValue(Node node, Rational value, Node pathHead,
					Node pathTail)
				{
					if (node.getName().equals(targetNodeName)) {
						System.out.printf("%s -> %s: %s%n", pathHead.getName(),
							pathTail.getName(), value);
					}
				}
			});
		}
		
		Map<Node, Rational> utils = uc.getUtilities(graph);
		
		if (!quiet) {
			List<Node> nodes = new ArrayList<Node>(graph);
			
			Collections.sort(nodes);
			int maxNameLength = 0;
			
			int i = 1;
			for (Node n : nodes) {
				String name = n.getName();
				int length;
				if (name == null)
					name = String.format("(null #%d)", i++);
				
				length = name.length();
				if (length > maxNameLength)
					maxNameLength = length;
			}
			
			if (targetNodeName != null) {
				System.out.println("===============================");
			}
			
			for (Node n : nodes) {
				String name = n.getName();
				char[] spacing = new char[maxNameLength - name.length() + 1];
				Arrays.fill(spacing, ' ');
				System.out.printf("%s:%s%s%n", name, new String(spacing),
					utils.get(n));
			}
		}
	}
	
	public static void main(String... args)
	{
		ArgumentParser parser = new ArgumentParser();
		
		parser.addOption("trace", "-t", "--trace").setValueType(String.class);
		parser.addOption("quiet", "-q", "--quiet").setDefaultValue(false)
			.setImplicitValue(true);
		
		try {
			ArgumentParser.Result result = parser.parse(args);
			
			if (result.args.length <= 0) {
				throw new ArgumentParseException("must provide graph file");
			}
			
			String filename = result.args[0];
			String traceNodeName = (String) result.options.get("trace");
			boolean quiet = (Boolean.TRUE == result.options.get("quiet"));
			
			printUtilities(Simulator.readNetwork(filename), quiet,
				traceNodeName);
		} catch (ArgumentParseException e) {
			System.err.println("error: " + e.getMessage());
			System.exit(-1);
			return;
		}
	}
}
